Cleaning Robot
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 4395   Accepted: 1763

Description

Here, we want to solve path planning for a mobile robot cleaning a rectangular room floor with furniture.

Consider the room floor paved with square tiles whose size fits the cleaning robot (1 * 1). There are 'clean tiles' and 'dirty tiles', and the robot can change a 'dirty tile' to a 'clean tile' by visiting the tile. Also there may be some obstacles (furniture) whose size fits a tile in the room. If there is an obstacle on a tile, the robot cannot visit it. The robot moves to an adjacent tile with one move. The tile onto which the robot moves must be one of four tiles (i.e., east, west, north or south) adjacent to the tile where the robot is present. The robot may visit a tile twice or more.

Your task is to write a program which computes the minimum number of moves for the robot to change all 'dirty tiles' to 'clean tiles', if ever possible.

Input

The input consists of multiple maps, each representing the size and arrangement of the room. A map is given in the following format.

w h
c11 c12 c13 ... c1w
c21 c22 c23 ... c2w
...
ch1 ch2 ch3 ... chw

The integers w and h are the lengths of the two sides of the floor of the room in terms of widths of floor tiles. w and h are less than or equal to 20. The character cyx represents what is initially on the tile with coordinates (x, y) as follows.

'.' : a clean tile
'*' : a dirty tile
'x' : a piece of furniture (obstacle)
'o' : the robot (initial position)

In the map the number of 'dirty tiles' does not exceed 10. There is only one 'robot'.

The end of the input is indicated by a line containing two zeros.

Output

For each map, your program should output a line containing the minimum number of moves. If the map includes 'dirty tiles' which the robot cannot reach, your program should output -1.

Sample Input

7 5
.......
.o...*.
.......
.*...*.
.......
15 13
.......x.......
...o...x....*..
.......x.......
.......x.......
.......x.......
...............
xxxxx.....xxxxx
...............
.......x.......
.......x.......
.......x.......
..*....x....*..
.......x.......
10 10
..........
..o.......
..........
..........
..........
.....xxxxx
.....x....
.....x.*..
.....x....
.....x....
0 0

Sample Output

8
49
-1

分析:BFS得到邻接矩阵,这样就是一个固定起点的TSP问题,再用递归DFS(也叫回溯法)+剪枝,就可以得到答案。
问题:输入数据是连续的,直到0 0终止。倒腾了好久都是WA,居然是这个原因。。。。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 #define MAX_MAX 65535
  5 #define MAX_ROOM 25
  6 #define MAX_DIRT 15
  7 #define Q_LEN 10000
  8 
  9 typedef struct
 10 {
 11     int x;
 12     int y;
 13     int step;
 14 }T_Node;
 15 
 16 const int deltax[4] = {-1, 0, 1, 0};
 17 const int deltay[4] = {0, 1, 0, -1};
 18 
 19 T_Node gatDirt[MAX_DIRT];
 20 T_Node queue[Q_LEN];
 21 int gwLen;
 22 int gwWide;
 23 int gwDirtNum = 1;
 24 char gawMap[MAX_ROOM][MAX_ROOM];
 25 int gawDist[MAX_DIRT][MAX_DIRT];
 26 
 27 int BFS(T_Node *ptStart, T_Node *ptEnd)
 28 {
 29     int head = 0;
 30     int tail = 1;
 31     int direction = 0;
 32     char Map[MAX_ROOM][MAX_ROOM];
 33     queue[head] = *ptStart;
 34 
 35     int i,j;
 36     for(j=0; j<gwLen; j++)
 37     {
 38         for(i=0; i<gwWide; i++)
 39         {
 40             Map[j][i] = gawMap[j][i];
 41         }
 42     }
 43 
 44     Map[ptStart->y][ptStart->x] = 'x';
 45     while(head != tail)
 46     {
 47         for(direction=0; direction<4; direction++)
 48         {
 49             if(queue[head].x + deltax[direction] < 0
 50                    || queue[head].x + deltax[direction] >= gwWide
 51                     || queue[head].y + deltay[direction] < 0
 52                      || queue[head].y + deltay[direction] >= gwLen)
 53                 continue;
 54             queue[tail].x = queue[head].x + deltax[direction];
 55             queue[tail].y = queue[head].y + deltay[direction];
 56             if(queue[tail].x == ptEnd->x && queue[tail].y == ptEnd->y)
 57             {
 58                 return queue[head].step + 1;
 59             }
 60             if(Map[queue[tail].y][queue[tail].x] != 'x')
 61             {
 62                 queue[tail].step = queue[head].step + 1;
 63                 Map[queue[tail].y][queue[tail].x] = 'x';
 64                 tail++;
 65             }
 66         }
 67         head++;
 68     }
 69     return -1;
 70 }
 71 
 72 int gawIsCleaned[MAX_DIRT];
 73 int gwBest = MAX_MAX;
 74 
 75 void DFS(int sum, int position, int deep)
 76 {
 77     int k = 0;
 78     int ThisSum = sum;
 79     deep++;
 80     if(deep == gwDirtNum)
 81         if(sum < gwBest)
 82         {
 83             gwBest = sum;
 84             return;
 85         }
 86     for(k=0; k<gwDirtNum; k++)
 87     {
 88         if(gawDist[position][k] ==0 || gawIsCleaned[k] ==1)
 89         {
 90             continue;
 91         }
 92         sum += gawDist[position][k];
 93         if(sum > gwBest)
 94             break;
 95         gawIsCleaned[position] = 1;
 96         DFS(sum, k, deep);
 97         sum = ThisSum;
 98         gawIsCleaned[position] = 0;
 99     }
100     return;
101 }
102 
103 int main(void)
104 {
105     int i,j;
106     while(scanf("%d %d", &gwWide, &gwLen))
107     {
108         getchar();
109         if(gwWide == 0 || gwLen == 0)
110         {
111             return 0;
112         }
113         gwDirtNum = 1;
114         for(j=0; j<gwLen; j++)
115         {
116             for(i=0; i<gwWide; i++)
117             {
118                 scanf("%c", &gawMap[j][i]);
119                 if(gawMap[j][i] == '*')
120                 {
121                     gatDirt[gwDirtNum].x = i;
122                     gatDirt[gwDirtNum].y = j;
123                     gwDirtNum++;
124                 }
125                 if(gawMap[j][i] == 'o')
126                 {
127                     gatDirt[0].x = i;
128                     gatDirt[0].y = j;
129                 }
130             }
131             getchar();
132         }
133         for(j=0; j<gwDirtNum; j++)
134         {
135             for(i=j+1; i<gwDirtNum; i++)
136             {
137                 gawDist[j][i] = BFS(&gatDirt[i], &gatDirt[j]);
138                 if(gawDist[j][i] == -1)
139                 {
140                     gwBest = 0;
141                     break;
142                 }
143                 if(j != 0) gawDist[i][j] = gawDist[j][i];
144             }
145         }
146 
147         if(gwBest == 0)
148         {
149             gwBest = MAX_MAX;
150             printf("-1\n");
151         }
152         else
153         {
154             gwBest = MAX_MAX;
155             DFS(0, 0, 0);
156             printf("%d\n", gwBest);
157         }
158     }
159     return 0;
160 }